

#include "cybertron/core/IdAllocator.hpp"

CYBERTRON_BEGIN

CybertronCoreAPI IdAllocator::IdAllocator()
{
	zeroMembers();
}

CybertronCoreAPI IdAllocator::~IdAllocator()
{
	clear();
}

CybertronCoreAPI void IdAllocator::zeroMembers()
{
	mMinimalId = 1;
	mMaximalId = 0x7fffffff;
	mCurrentMaximalId = mMinimalId;
}

CybertronCoreAPI void IdAllocator::clear()
{
	mFreeIds.clear();
	mIsFreeFlags.clear();

	zeroMembers();
}

CybertronCoreAPI void IdAllocator::reset(int minimalId, int maximalId)
{
	clear();

	if (minimalId < 1)
	{
		minimalId = 1;
	}
	if (maximalId < minimalId)
	{
		maximalId = minimalId;
	}

	mMinimalId = minimalId;
	mMaximalId = maximalId;
	mCurrentMaximalId = mMinimalId;
}

CybertronCoreAPI int IdAllocator::allocateId()
{
	int id = -1;
	if (mFreeIds.size() > 0)
	{
		id = mFreeIds.back();
		mIsFreeFlags[id] = false;
		mFreeIds.pop_back();
	}
	else
	{
		id = mCurrentMaximalId;
		mCurrentMaximalId++;

		mIsFreeFlags.resize(mCurrentMaximalId);
		mIsFreeFlags[id] = false;
	}

	return id;
}

CybertronCoreAPI void IdAllocator::releaseId(int id)
{
	if (id < 0 || id >= (int)(mIsFreeFlags.size()))
	{
		return;
	}
	if (mIsFreeFlags[id])
	{
		// should not happen!
		return;
	}

	mIsFreeFlags[id] = true;
	mFreeIds.push_back(id);
}

CYBERTRON_END
